package main

import (
	"encoding/gob"
	"errors"
	"fmt"
	"gitee.com/MrDaiM/goodscenter/model"
	"gitee.com/MrDaiM/goodscenter/service"
	"gitee.com/MrDaiM/msgo"
	"gitee.com/MrDaiM/msgo/breaker"
	"gitee.com/MrDaiM/msgo/register"
	"gitee.com/MrDaiM/msgo/rpc"
	"gitee.com/MrDaiM/msgo/tracer"
	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"
	"github.com/uber/jaeger-client-go/config"
	"log"
	"net/http"
	"time"
)

func main() {

	engine := msgo.Default()

	// 限流
	//engine.Use(msgo.Limiter(1, 1))

	engine.Use(msgo.Tracer("goodsService", &config.SamplerConfig{
		Type:  jaeger.SamplerTypeConst,
		Param: 1,
	}, &config.ReporterConfig{
		LogSpans:          true,
		CollectorEndpoint: "http://192.168.152.136:14268/api/traces",
	}, config.Logger(jaeger.StdLogger)))

	// 熔断
	settings := breaker.Settings{}
	settings.Fallback = func(err error) (any, error) {
		goods := &model.Goods{Id: 9002, Name: fmt.Sprintf("%s-参数:%s", "降级9002的商品", "-1")}
		return goods, err
	}
	cb := breaker.NewCircuitBreaker(settings)

	group := engine.Group("goods")

	createTracer, closer, err := tracer.CreateTracer("goodsCenter", &config.SamplerConfig{
		Type:  jaeger.SamplerTypeConst,
		Param: 1,
	}, &config.ReporterConfig{
		LogSpans:          true,
		CollectorEndpoint: "http://192.168.152.136:14268/api/traces",
	}, config.Logger(jaeger.StdLogger))
	if err != nil {
		panic(err)
	}
	defer closer.Close()

	group.Get("/findTrace", func(ctx *msgo.Context) {
		span := createTracer.StartSpan("findTracer")
		defer span.Finish()
		B(createTracer, span)
		query := ctx.GetQuery("id")
		goods := &model.Goods{Id: 9002, Name: fmt.Sprintf("%s-参数:%s", "9002的商品", query)}
		_ = ctx.JSON(http.StatusOK, model.Result{Code: 200, Msg: "请求成功", Data: goods})
	})

	group.Get("/find", func(ctx *msgo.Context) {

		goods, err := cb.Execute(func() (any, error) {
			query := ctx.GetQuery("id")
			if query == "2" {
				return nil, errors.New("测试熔断")
			}
			headerVal := ctx.GetHeader("my")
			ctx.Logger.Info(headerVal)

			goods := &model.Goods{Id: 9002, Name: fmt.Sprintf("%s-参数:%s", "9002的商品", query)}

			return goods, nil
		})
		log.Println(err)
		//if err != nil {
		//	_ = ctx.JSON(http.StatusInternalServerError, model.Result{Code: 500, Msg: err.Error()})
		//	return
		//}
		_ = ctx.JSON(http.StatusOK, model.Result{Code: 200, Msg: "请求成功", Data: goods})
	})
	group.Post("/find", func(ctx *msgo.Context) {
		goods := &model.Goods{Id: 9002, Name: "9002的商品"}
		_ = ctx.JSON(http.StatusOK, model.Result{Code: 200, Msg: "请求成功", Data: goods})
	})

	//go func() {
	//	server := grpc.NewServer()
	//	api.RegisterGoodsApiServer(server, &api.GoodsRpcService{})
	//	listen, _ := net.Listen("tcp", ":9111")
	//	err := server.Serve(listen)
	//	log.Println(err)
	//	log.Println("============================================")
	//}()

	//go func() {
	//	grpcServer, _ := rpc.NewGrpcServer(":9111")
	//	grpcServer.Register(func(grpcServer *grpc.Server) {
	//		api.RegisterGoodsApiServer(grpcServer, &api.GoodsRpcService{})
	//	})
	//	err := grpcServer.Run()
	//	panic(err)
	//}()

	go func() {

		// gob序列化和反序列化  同一目录的对象是不需要进行注册的，不同服务间传递的相同对象，使用前需要进行注册
		gob.Register(&model.Result{})
		gob.Register(&model.Goods{})

		tcpServer := rpc.NewTcpServer("127.0.0.1", 9222)
		// tcp 限流设置
		tcpServer.LimiterTimeOut = time.Second
		tcpServer.SetLimiter(1, 1)
		tcpServer.SetRegister("etcd", register.Option{
			Endpoints:   []string{"127.0.0.1:2379"},
			DialTimeout: 5 * time.Second,
			Host:        "127.0.0.1",
			Port:        9222,
		})

		tcpServer.Register("goods", &service.GoodsRpcService{})
		tcpServer.Run()
	}()

	cli := register.MsETCDRegister{}
	cli.CreateCli(register.Option{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: 5 * time.Second,
	})
	cli.RegisterService("goodsCenter", "127.0.0.1", 9002)

	engine.Run(":9002")
}

func B(createTracer opentracing.Tracer, span opentracing.Span) {
	log.Println("调用了一个b方法")
	startSpan := createTracer.StartSpan("B", opentracing.ChildOf(span.Context()))
	defer startSpan.Finish()
}
